#include "kvs.h"
#include "proactor.h"

#define PA_MAX_TOKEN_NUM 150  // 一次最多分包数量


// ======================分包函数 (仿照reactor)============================
int proactor_split_by_etx(char *msg, char *tokens[]);
int proactor_process_received_data(proactor_conn *conn, ssize_t ret);
// ======================================================================================

int proactor_entry(int port)
{
    int sockfd = proactor_init_server(port);
    if (sockfd == -1)
    {
        return -1;
    }
    LOG("监听端口 %d 成功\n", port);

    struct io_uring_params params;
    memset(&params, 0, sizeof(params));
    struct io_uring ring;
    if (io_uring_queue_init_params(ENTRIES_LENGTH, &ring, &params) != 0)
    {
        perror("io_uring初始化失败");
        close(sockfd);
        return -1;
    }

    proactor_conn *listen_conn = pa_register_conn(sockfd, 1);
    if (!listen_conn)
    {
        LOG("listen_conn init faile\n");
        return -1;
    }
    set_event_accept(&ring, listen_conn);

    while (1)
    {
        int ret = io_uring_submit(&ring);
        if (ret < 0)
        {
            perror("io_uring_submit失败");
            break;
        }

        struct io_uring_cqe *cqes[128];
        int nready = io_uring_peek_batch_cqe(&ring, cqes, 128);
        if (nready < 0)
        {
            perror("io_uring获取完成事件失败");
            break;
        }

        for (int i = 0; i < nready; i++)
        {
            struct io_uring_cqe *cqe = cqes[i];
            proactor_conn *conn = (proactor_conn *)(cqe->user_data);

            // 处理accept事件（新连接）
            if (conn->event == EVENT_ACCEPT)
            {
                set_event_accept(&ring, conn);

                int connfd = cqe->res;
                if (connfd == -1)
                {
                    perror("接受连接失败");
                }
                else
                {

                    LOG("新连接：fd=%d\n", connfd);

                    // proactor_conn *conn = kvs_malloc(sizeof(proactor_conn));
                    proactor_conn *new_conn = pa_register_conn(connfd, 0);
                    if (!new_conn)
                    {
                        perror("kvs_malloc new_ctx失败");
                        close(connfd);
                    }
                    else
                    {
                        set_event_recv(&ring, new_conn);
                    }
                }
                // 每处理完一次都需要调用
                safe_release_conn(conn);
            }

            // 处理读事件（接收数据）
            else if (conn->event == EVENT_RECV)
            {
                ssize_t recv_len = cqe->res;
                if (recv_len <= 0)
                {
                    // LOG("连接fd=%d 准备关闭（recv_len=%zd）\n", conn->fd, recv_len);
                    conn->is_closing = 1;
                }
                else
                {
                    // 调用封装后的粘包处理函数
                    proactor_process_received_data(conn, recv_len);

                    // 业务处理：从rlink取完整包，处理后放入wlink
                    kvs_request(&conn->rlink, &conn->wlink);
                    clear_list(&conn->rlink);

                    // 注册写事件发送响应
                    set_event_send(&ring, conn);
                }

                // 每处理完一次都需要调用
                safe_release_conn(conn);
            }

            // 处理写事件（发送数据）
            else if (conn->event == EVENT_SEND)
            {
                ssize_t sent_len = cqe->res;
                if (sent_len <= 0)
                {
                    // LOG("发送失败：fd=%d（sent_len=%zd）\n", conn->fd, sent_len);
                    conn->is_closing = 1;
                }
                else
                {

                    node *send_node = conn->wlink.next;
                    if (send_node == &conn->wlink) // 判断发送的是否为空包
                    {
                        set_event_recv(&ring, conn);
                        safe_release_conn(conn);
                        continue;
                    }

                    conn->idx += sent_len;
                    // LOG("发送成功：fd=%d，已发=%zd，当前偏移=%d，节点总长度=%d\n",conn->fd, sent_len, conn->idx, send_node->length);

                    if (conn->idx >= send_node->length)
                    {
                        delete_node(send_node, &conn->wlink);
                        conn->idx = 0;
                        // LOG("节点发送完成：fd=%d，已删除节点\n", conn->fd);
                    }

                    if (!list_empty(&conn->wlink))
                    {
                        // 如果还有数据继续发送
                        set_event_send(&ring, conn);
                    }
                    else
                    {
                        set_event_recv(&ring, conn);
                    }
                }

                safe_release_conn(conn);
            }

            io_uring_cqe_seen(&ring, cqe);
        }
    }

    io_uring_queue_exit(&ring);
    close(sockfd);
    return 0;
}

// ====================================分包函数（仿照reactor)============================
// 按分隔符\x03拆分数据（粘包处理）
int proactor_split_by_etx(char *msg, char *tokens[])
{
    int idx = 0;
    char *token = strtok(msg, "\x03");
    while (token != NULL && idx < 16) // 限制最大16个包，避免越界
    {
        tokens[idx++] = token;
        token = strtok(NULL, "\x03");
    }
    return idx;
}

// 处理接收数据，拆分粘包并填充到接收链表rlink
int proactor_process_received_data(proactor_conn *conn, ssize_t ret)
{
    int flag = 0; // 最后一个分段是否为完整指令的标志
    char *buffer = conn->buffer;
    buffer[ret] = '\0'; // 确保字符串结束

    // 检查最后一个字符是否为分隔符（完整包标志）
    if (buffer[ret - 1] == '\x03')
    {
        flag = 1;
    }

    // 处理特殊情况：当前缓冲区开头是分隔符（衔接上一次的半包结尾）
    if (buffer[0] == '\x03')
    {
        if (!list_empty(&conn->remain_link))
        {
            int total_len = conn->remain_link.length + conn->remain_len + 1;
            char *buf = kvs_malloc(total_len);
            memset(buf, 0, total_len);
            int len = proactor_fill_with_list(buf, conn->remain_link.length, &conn->remain_link);
            memcpy(buf + len, conn->remain_buffer, conn->remain_len);
            insert_list(buf, total_len, &conn->rlink);
            clear_list(&conn->remain_link);
            conn->remain_len = 0;
            memset(conn->remain_buffer, 0, PA_BUFFER_LENGTH);
            kvs_free(buf);
        }
        else
        {
            insert_list(conn->remain_buffer, conn->remain_len + 1, &conn->rlink);
            conn->remain_len = 0;
            memset(conn->remain_buffer, 0, PA_BUFFER_LENGTH);
        }
    }

    // 按分隔符拆分当前缓冲区数据
    char *tokens[PA_MAX_TOKEN_NUM] = {NULL};
    int count = proactor_split_by_etx(buffer, tokens);

    if (count == 0)
    {
        LOG("count == 0\n");
        return 0;
    }

    // 处理前count-1个完整分段（除最后一个外）
    for (int i = 0; i < count - 1; i++)
    {
        // 若有上一次遗留的半包数据，先合并再插入
        if (i == 0 && conn->remain_len != 0)
        {
            if (!list_empty(&conn->remain_link))
            {
                int total_len = conn->remain_link.length + conn->remain_len + strlen(tokens[i]) + 1;
                char *buf = kvs_malloc(total_len);
                memset(buf, 0, total_len);
                int len = proactor_fill_with_list(buf, conn->remain_link.length, &conn->remain_link);
                memcpy(buf + len, conn->remain_buffer, conn->remain_len);
                memcpy(buf + len + conn->remain_len, tokens[i], strlen(tokens[i]) + 1);
                insert_list(buf, total_len, &conn->rlink);
                clear_list(&conn->remain_link);
                conn->remain_len = 0;
                memset(conn->remain_buffer, 0, PA_BUFFER_LENGTH);
                kvs_free(buf);
                continue;
            }
            else
            {
                if (conn->remain_len + strlen(tokens[i]) + 1 > PA_BUFFER_LENGTH)
                {
                    char *buf = kvs_malloc(conn->remain_len + strlen(tokens[i]) + 1);
                    memset(buf, 0, conn->remain_len + strlen(tokens[i]) + 1);
                    memcpy(buf, conn->remain_buffer, conn->remain_len);
                    memcpy(buf + conn->remain_len, tokens[i], strlen(tokens[i]) + 1);
                    insert_list(buf, conn->remain_len + strlen(tokens[i]) + 1, &conn->rlink);
                    conn->remain_len = 0;
                    memset(conn->remain_buffer, 0, PA_BUFFER_LENGTH);
                    kvs_free(buf);
                    continue;
                }
                else
                {
                    memcpy(conn->remain_buffer + conn->remain_len, tokens[i], strlen(tokens[i]) + 1);
                    insert_list(conn->remain_buffer, conn->remain_len + strlen(tokens[i]) + 1, &conn->rlink);
                    conn->remain_len = 0;
                    memset(conn->remain_buffer, 0, PA_BUFFER_LENGTH);
                    continue;
                }
            }
        }
        // 无遗留数据，直接插入当前分段
        insert_list(tokens[i], strlen(tokens[i]) + 1, &conn->rlink);
    }

    // 处理最后一个分段（根据flag判断是否完整）
    if (flag == 1)
    {
        // 最后一个分段是完整包，合并遗留数据后插入
        if (conn->remain_len != 0)
        {
            if (!list_empty(&conn->remain_link))
            {
                int total_len = conn->remain_link.length + conn->remain_len + strlen(tokens[count - 1]) + 1;
                char *buf = kvs_malloc(total_len);
                memset(buf, 0, total_len);
                int len = proactor_fill_with_list(buf, conn->remain_link.length, &conn->remain_link);
                memcpy(buf + len, conn->remain_buffer, conn->remain_len);
                memcpy(buf + len + conn->remain_len, tokens[count - 1], strlen(tokens[count - 1]) + 1);
                insert_list(buf, total_len, &conn->rlink);
                clear_list(&conn->remain_link);
                conn->remain_len = 0;
                memset(conn->remain_buffer, 0, PA_BUFFER_LENGTH);
                kvs_free(buf);
            }
            else
            {
                if (conn->remain_len + strlen(tokens[count - 1]) + 1 > PA_BUFFER_LENGTH)
                {
                    char *buf = kvs_malloc(conn->remain_len + strlen(tokens[count - 1]) + 1);
                    memset(buf, 0, conn->remain_len + strlen(tokens[count - 1]) + 1);
                    memcpy(buf, conn->remain_buffer, conn->remain_len);
                    memcpy(buf + conn->remain_len, tokens[count - 1], strlen(tokens[count - 1]) + 1);
                    insert_list(buf, conn->remain_len + strlen(tokens[count - 1]) + 1, &conn->rlink);
                    conn->remain_len = 0;
                    memset(conn->remain_buffer, 0, PA_BUFFER_LENGTH);
                    kvs_free(buf);
                }
                else
                {
                    memcpy(conn->remain_buffer + conn->remain_len, tokens[count - 1], strlen(tokens[count - 1]) + 1);
                    insert_list(conn->remain_buffer, conn->remain_len + strlen(tokens[count - 1]) + 1, &conn->rlink);
                    conn->remain_len = 0;
                    memset(conn->remain_buffer, 0, PA_BUFFER_LENGTH);
                }
            }
        }
        else
        {
            // 无遗留数据，直接插入最后一个完整分段
            insert_list(tokens[count - 1], strlen(tokens[count - 1]) + 1, &conn->rlink);
        }
    }
    else if (flag == 0)
    {
        // 最后一个分段是半包，存入遗留数据区
        int last_len = strlen(tokens[count - 1]);
        if (conn->remain_len + last_len + 1 > PA_BUFFER_LENGTH)
        {
            insert_list(conn->remain_buffer, conn->remain_len, &conn->remain_link);
            memset(conn->remain_buffer, 0, PA_BUFFER_LENGTH);
            memcpy(conn->remain_buffer, tokens[count - 1], last_len);
            conn->remain_len = last_len;
        }
        else
        {
            memcpy(conn->remain_buffer + conn->remain_len, tokens[count - 1], last_len);
            conn->remain_len += strlen(tokens[count - 1]);
        }
        count = count - 1;
    }
    return count;
}
// ======================================================================================